When a business wants to communicate something to all its customers, e.g. the announcement of a new product, it can send out form letters to all its existing customers. Each such letter has the same contents, except for a few differences like the name and address of the respective customer. Mail merge is the process of creating these form letters out of a letter template and a customer database.
This example shows how Oberon/F's built-in text facilities can be used to implement a simple mail merge extension.
Mail Merge Process
To try out ObxMMerge, compile it, install the following command in some menu:
(mmTmpl) in the Obx/Samples directory and then execute the Merge command. A dialog box will ask you for the address database; open the mail merge
document
(mmData) in the Obx/Samples directory.
As a result, a new text is created which contains a sequence of form letters. When you execute the Show
Marks command in the Text menu, you'll note that the individual letters are separated by page-breaking rulers.
Now let's take a closer look at how the program is implemented. There is one command called Merge, which gets the template text (the focus), searches for place holders in this text (the fields of the template), then lets the user open the database text, determines for each template field which column of the database text corresponds to the field, creates a new output text, adds an instance of the letter template for every row of the database text, and finally opens the text in a window.
Outline of the ObxMMerge Program:
There are five auxiliary procedures which are called by Merge:
TmplFields analyzes the template text, and returns a list of fields for this text. Each field describes a place holder with its name and its position in the text. Place holders are specified as names between "<" and ">" characters, e.g. <Name>.
ThisDatabase asks the user for a database document, and returns the text contained in this document.
MergeFields determines for every template field the corresponding database column. To make this possible, the first row of the database text must contain the so-called meta data of the database. For mail merge applications, this is simply the symbolic name of every column, e.g. Name or City. This name must be identical to the name used in the template.
Each row is terminated by a carriage return (0DX), and the fields of a row (the columns) are separated by tabs (09X).
ReadTuple reads one row of the database text, and assigns the text range occupied by one database field to every corresponding template field.
AppendInstance appends a copy of the template text to the end of the output text, and then replaces all the place holders by the contents of their respective database fields. These replacements are done from the end of the appended text towards the beginning, so that from/to indices are not invalidated by replacements. This explains why the field list is built up in reverse order, last field first.
Note that each replacement gets the text attributes of the first replaced character, i.e. if the place holder "<Name>" in bold face is replaced by the string "Joe", the resulting replacement will be 'Joe".
ObxMMerge doesn't insert page-breaking rulers of its own; instead, the template text contains such a ruler.